
package domain;

import java.util.Iterator;
import java.util.Vector;

/**
 *
 * @author shaigi
 */
public class Game {

    public static enum  action { RIGHT, LEFT, UP, DOWN, SHOOT };
    
    // configurations:
    public static final int STEP_COST   = 1;
    public static final int FLAG_VALUE  = 3;
    public static final int NO_FLAG     = 0;
    public static final int DELAY       = 200;
	//public static final int INITIALE_SCORE = 20;
    public static final int INITIALE_SCORE = 0;
	
	public static Board     		_board;
    private static Vector<Agent>	_agents;	//TODO: Changed to Static (by ika) see if it is good
    private int             		_stepsTMP   = 30;  	//TODO del
    private boolean					_gameDeterministic;
    private static boolean			_gameZeroSum;
    private double					_slippingOnIceProbability;
    private int						_arsenal;
    private String					_assignment;
    
    
    
    public Game(Board board, boolean gameDeterministic, boolean gameZeroSum, int arsenal, String assignment) {
        
        Game._board     				= board;
        this._agents    				= new Vector<Agent>();
        this._gameDeterministic			= gameDeterministic;
        this._gameZeroSum				= gameZeroSum;
        setSlippingOnIceProbability();
        this._arsenal					= arsenal;
        this._assignment				= assignment;
                
        System.out.println("Game created, p = " + this._slippingOnIceProbability);
    }
    
    private void setSlippingOnIceProbability() {
		if ( this._gameDeterministic ){
			this._slippingOnIceProbability = 1.0;
		}
		else{
			this._slippingOnIceProbability = Math.random();
		}
	}

	public void start(){
        //@TODO complete code here
        
        //making automatic move on the entire Board
        while (!endOfGame()){
            try {
                Thread.sleep(DELAY);
            } catch (InterruptedException ex) {
                System.out.println("cant sleep");
            }
            for (Iterator<Agent> it = _agents.iterator(); it.hasNext();) {
                Agent agent = it.next();
                System.out.println("=====================\n " + agent.getName()+"'s turn:\n=====================");
                agent.play(Game._board, _agents);
                try {
                    Thread.sleep(DELAY);
                } catch (InterruptedException ex) {}
            }
        }
    }

    public static Vector<Agent> getAgents() {
    	return _agents;
    }
    
    public void initialize() {
    	
        // For assignment 1:
    	if (this._assignment.equals("1")){
	    	//Agent moshe = new AgentDumbAuto("sentry", action.RIGHT, Integer.MAX_VALUE, this._assignment);
    		Agent moshe = new AgentDumbAuto("sentry", action.RIGHT, this._assignment);
	    	addAgent(moshe);
	        
	        //Agent smarty = new AgentSmart("smarty", action.RIGHT, 0, this._assignment);
	        Agent smarty = new AgentSmart("smarty", action.RIGHT, this._assignment);
	        addAgent(smarty);
	        
	        moshe.setEnemy(smarty);
	        smarty.setEnemy(moshe);
    	}
    	
    	
        // For assignment 2:
    	if (this._assignment.equals("2.1")){
	        //Agent onlyHuman = new AgentHuman("human_sentry", action.RIGHT, this._arsenal, this._assignment);
    		Agent onlyHuman = new AgentHuman("human_sentry", action.RIGHT, this._assignment);
	        addAgent(onlyHuman);
	
	        //Agent smarty = new AgentSmart("smarty", action.RIGHT, this._arsenal, this._assignment);
	        Agent smarty = new AgentSmart("smarty", action.RIGHT, this._assignment);
	        addAgent(smarty);
	        
	        onlyHuman.setEnemy(smarty);
	        smarty.setEnemy(onlyHuman);
    	}
        
        
        
        //Agent smith = new AgentGreedy("smith", action.RIGHT);
        //addAgent(smith);
        //TODO add more agents here
    }
    public void placeAgents(){
    	// For assignment 1:
    	if (this._assignment.equals("1")){
	        _agents.elementAt(0).placeAgent(_board.getSquare(2, 3));
	        _agents.elementAt(1).placeAgent(_board.getSquare(6, 1));
    	} else if (this._assignment.equals("2.1")){
	        _agents.elementAt(0).placeAgent(_board.getSquare(1, 1));
	        _agents.elementAt(1).placeAgent(_board.getSquare(2, 2));
    	}
    }
    
    public int getNumberOfAgents(){
        return _agents.size();
    }

    private void addAgent(Agent newAgent) {
        _agents.addElement(newAgent);
        //TODO update GUI
    }

    private boolean endOfGame() {
    	this._stepsTMP--;
    	return this._stepsTMP == 0 || _board.getFlags().isEmpty();
    }

	public static Agent getOtherPlayer(Agent agent) {
		if (_agents.size() != 2){
			return null;
		}
		else{
			if (_agents.elementAt(0) == agent)
				return _agents.elementAt(1);
			else if (_agents.elementAt(1) == agent)
				return _agents.elementAt(0);
			else
				return null;
		}
	}
	
	public static boolean isGameZeroSum() {
		return _gameZeroSum;
	}

	public static void increaseScoreBy(int adding, Agent agent, Agent otherAgent) {
    	agent.setScore(agent.getScore() + adding);
    	// If the game is zero sum, decrease other player's score:
    	if ( Game.isGameZeroSum() ){
    		otherAgent.setScore(otherAgent.getScore() - adding);
    	}
    
	}
}